var jsq={
    Version: '%%VERSION%%',
    Build: '%%BUILD%%',
    
    Browser: {
        IE:     !!(window.attachEvent && !window.opera),
        Opera:  !!window.opera,
        WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
        Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
        MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
    },
    
    ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
    emptyFunction: function() { },
    
    extendNotExist : function(destination, source) {
        for (var property in source)
            if (typeof destination[property]=='undefined') destination[property] = source[property];
        return destination;
    },
    extend : function(destination, source) {
        for (var property in source)
            destination[property] = source[property];
        return destination;
    },
    include:function(url) {
    	var head=document.getElementsByTagName("head");
    	if (head) {
    		var linkel=document.createElement('script');
    		linkel.setAttribute('src', url);
    		linkel.setAttribute('type', 'text/javascript');
    		head[0].appendChild(linkel);
    	}
    	head=null;
    },
    namespace:function(name,define) {
    	var names=name.split('.');
    	var obj=window;
    	var last=names.length-1;
    	var ns='';
    	for(i=0;i<last;i++) {
    	    if (ns.length>0) ns+='.';
    	    ns+=names[i];
    		if (typeof obj[names[i]]=='undefined') obj[names[i]]={NAMESPACE:ns};
    		obj=obj[names[i]];
    	}
    	if (!obj[names[last]]) {
    		if (define) {
    			obj[names[last]]=define;
    			(obj[names[last]]).NAMESPACE=name;
    		}
    		else obj[names[last]]={NAMESPACE:name};
    	}
    	obj=null;
    },
    // type checking from prototype.js
    isElement: function(object) {
        return object && object.nodeType == 1;
    },
    isArray: function(object) {
        return object != null && typeof object == "object" && 'splice' in object && 'join' in object;
    },
    isFunction: function(object) {
        return typeof object == "function";
    },
    isString: function(object) {
        return typeof object == "string";
    },
    isNumber: function(object) {
        return typeof object == "number";
    },
    isUndefined: function(object) {
        return typeof object == "undefined";
    },
    // type checking jsquare native
    isCollection: function(object) {
        return object && length in object && object[0];
    },
    isClass:function(object) {
        return object && object.isJsqClass==true;
    }
};


// css function
jsq.css=function(element,className) {
	if (className) jsq.css.set(element.className);
	else return jsq.css.get(element);
};
jsq.css.set=function(element,className) {
	element.className=className;
	element._jsq_class_cache=className.split(' ');
};
jsq.css.add=function(element,className) {
	if (!element._jsq_class_cache) {
		element._jsq_class_cache=element.className.split(' ');
	}
	if (element._jsq_class_cache.find(className)>=0) return;
	element._jsq_class_cache.push(className);
	element.className=element._jsq_class_cache.join(' ');
};
jsq.css.get=function(element) {
	if (!element._jsq_class_cache) {
		element._jsq_class_cache=element.className.split(' ');
	}
	return element._jsq_class_cache;
};
jsq.css.remove=function(element,className) {
	if (!element._jsq_class_cache) {
		element._jsq_class_cache=element.className.split(' ');
	}
	var p=element._jsq_class_cache.find(className);
	if (p<0) return;
	element._jsq_class_cache=element._jsq_class_cache.splice(p,1);
	element.className=element._jsq_class_cache.join(' ');
};
jsq.css.getRule=function(selectorname) {
	var css=document.styleSheets;
	var rules,rule;
	for(var i=css.length-1;i>=0;i--) {
		try {
			if (css[i].cssRules) rules=css[i].cssRules;
			else if (css[i].rules) rules=css[i].rules;
		} catch(e) {
			continue;
		}
		for(var j=0;j<rules.length;j++) {
			rule=rules[j];
			if (rule.selectorText && rule.selectorText==selectorname) {
				return rule.style;
			}
		}
	}
	return null;
};
jsq.css.addRule=function(strName,strRule) {
	var head=document.getElementsByTagName("head");
	if (head) {
		var style=document.createElement('style');
		if (jsq.Browser.IE) {
			style.setAttribute('type','text/css');
			if(style.styleSheet){// IE
				style.styleSheet.cssText = strName+' {'+strRule+'}';
			} else {// w3c
				var cssText = document.createTextNode(strName+' {'+strRule+'}');
				style.appendChild(cssText);
				cssText=null;
			}
		} else {
			style.setAttribute('type','text/css');
			style.innerHTML=strName+' {'+strRule+'}';
		}
		head[0].appendChild(style);
		style=null;
	}
	head=null;
};
jsq.css.load=function(src) {
	var head=document.getElementsByTagName("head");
	if (head) {
		var linkel=document.createElement('link');
		linkel.setAttribute('href', src);
		linkel.setAttribute('rel', 'stylesheet');
		linkel.setAttribute('type', 'text/css');
		head[0].appendChild(linkel);
	}
	head=null;
};
jsq.style=function(element,property,value) {
	if (value) jsq.style.set(element,property,value);
	else return jsq.style.get(element,property);
};
jsq.style.set=function(element,property,value) {
	if (property=='opacity') jsq.style.opacity(element,value);
	else element.style[property] = value;
};
jsq.style.get=function(element,property) {
  var value = null;
  var dv = document.defaultView;
  
  if (jsq.Browser.IE && property == 'opacity') { // IE
  	value=1;
    if (value = (element.style.filter || '').match(/alpha\(opacity=(.*)\)/))
      if (value[1]) value=parseFloat(value[1]) / 100;
  }
/*  if (property == 'opacity' && element.filters) 	// IE
  {
     value = 1;
     try { value = element.filters.item('DXImageTransform.Microsoft.Alpha').opacity; } catch(e) {
        try { value = element.filters.item('alpha').opacity/100; } catch(e) {}
     }
  }*/
  else if (element.style[property]) {return element.style[property];}
  else if (element.currentStyle && element.currentStyle[property]) { return element.currentStyle[property];}
  else if ( dv && dv.getComputedStyle )
  {
     var converted = '';
     for(var i = 0, len = property.length;i < len; ++i) {
        if (property.charAt(i) == property.charAt(i).toUpperCase()) {
           converted = converted + '-' + property.charAt(i).toLowerCase();
        } else {
           converted = converted + property.charAt(i);
        }
     }
     if (dv.getComputedStyle(element, '') && dv.getComputedStyle(element, '').getPropertyValue(converted)) {
        value = dv.getComputedStyle(element, '').getPropertyValue(converted);
     }
  }
  element=null;
  return value;
};
jsq.style.opacity=function(element,value) {
	if (arguments.length>1) this.setOpacity(element,value);
	else return this.get(element,'opacity');
};
jsq.style._setOpacity_ie=function(element,value) {
	element.style.filter = 'alpha(opacity=' + (value*100) + ')';
	if (!element.currentStyle || !element.currentStyle.hasLayout) {element.style.zoom = 1;}
};
jsq.style._setOpacity_non_ie=function(element,value) {
	element.style.opacity = value;
  element.style['-moz-opacity'] = value;
  element.style['-khtml-opacity'] = value;
};
// process cross browsing
jsq.style.setOpacity = (jsq.Browser.IE)?jsq.style._setOpacity_ie:jsq.style._setOpacity_non_ie;

jsq.style.setFromObject=function(element,objStyle) {
	for(selector in objStyle) {
		this.set(element,selector,objStyle[selector]);
	}
};

// dom
jsq.dom={
	setPos:function(element,x,y,parentElement) {
		var pos=element.style.position?element.style.position:'static';
		var relative=(pos=='relative');
		var position=jsq.dom.getPos(element);
		var dx=parseInt(element.style.left,10);
		var dy=parseInt(element.style.top,10);
		if (isNaN(dx)) {dx=(relative)?0:element.offsetLeft;}
		if (isNaN(dy)) {dy=(relative)?0:element.offsetTop;}
		if (parentElement) {
			var ppos=jsq.dom.getPos(parentElement);
			dx+=ppos.x;
			dy+=ppos.y;
			parentElement=null;
		}
		position.x=x-position.x+dx;
		position.y=y-position.y+dy;
		element.style.left = position.x+'px';
		element.style.top = position.y+'px';
		element=null;
	},
	_getPosition_ie:function(element,parentElement) {
		var parent = null;
		var pos = {x:0,y:0};
		
		var rect = element.getBoundingClientRect();
		pos.x=rect.left + Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
		pos.y=rect.top + Math.max(document.documentElement.scrollTop, document.body.scrollTop);
		rect=null;
          
		if (parentElement) {
			var ppos=this._getPosition_ie(parentElement);
			pos.x-=ppos.x;
			pos.y-=ppos.y;
			parentElement=null;
			ppos=null;
		}
		element=null;
		parent=null;
		return {x:isNaN(pos.x)?0:pos.x,y:isNaN(pos.y)?0:pos.y};
	},
	_getPosition_ff:function(element,parentElement) {
    var parent = null;
    var pos = {x:0,y:0};
    
		var rect = document.getBoxObjectFor(element);
		pos = {x:rect.x, y:rect.y};
		rect=null;

    if (element.parentNode) { parent = element.parentNode; }
    else { parent = null; }

    while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') 
    {
       pos.x -= parent.scrollLeft;
	     pos.y -= parent.scrollTop;

       if (parent.parentNode) { parent = parent.parentNode; } 
       else { parent = null; }
    }
          
		if (parentElement) {
			var ppos=this._getPosition_ff(parentElement);
			pos.x-=ppos.x;
			pos.y-=ppos.y;
			parentElement=null;
			ppos=null;
		}
		element=null;
		parent=null;
		return {x:isNaN(pos.x)?0:pos.x,y:isNaN(pos.y)?0:pos.y};
	},
	_getPosition_etc:function(element,parentElement) {
		var parent = null;
		var pos = {x:0,y:0};
		
		pos = {x:element.offsetLeft, y:element.offsetTop};
		parent = element.offsetParent;
		if (parent != element) {
		  while (parent) {
		     pos.x += parent.offsetLeft;
		     pos.y += parent.offsetTop;
		     parent = parent.offsetParent;
		  }
		}
		if (jsq.Browser.Opera||( jsq.Browser.WebKit && element.style.position == 'absolute')) {
		  pos.x -= document.body.offsetLeft;
		  pos.y -= document.body.offsetTop;
		} 
		      
		if (parentElement) {
			var ppos=this._getPosition_etc(parentElement);
			pos.x-=ppos.x;
			pos.y-=ppos.y;
			parentElement=null;
			ppos=null;
		}
		element=null;
		parent=null;
		return {x:isNaN(pos.x)?0:pos.x,y:isNaN(pos.y)?0:pos.y};
	},
	_getPosition:null,
	getPos:function(element,parentElement) {
		if (!this._getPosition) {
			if (element.getBoundingClientRect) this._getPosition=this._getPosition_ie;
			else if (document.getBoxObjectFor) this._getPosition=this._getPosition_ff;
			else this._getPosition=this._getPosition_etc;
		}
		return this._getPosition(element,parentElement);
	},
	toRelative:function(x,y,element) {
		var pos={x:x,y:y};
		var ppos=this.getPosition(element);
		pos.x-=ppos.x;
		pos.y-=ppos.y;
		element=null;
		ppos=null;
		return pos;
	},
	setWidth:function(element,w) {		element.style.width=w+'px';	},
	setHeight:function(element,h) {		element.style.height=h+'px';	},
	getWidth:function(element) {		return element.offsetWidth;	},
	getHeight:function(element) {		return element.offsetHeight;	},
	setSize:function(element,w,h) {
		var els=element.style;
		if (jsq.isNumber(w)) els.width=w+'px';
		else els.width=w;
		if (jsq.isNumber(h)) els.height=h+'px';
		else els.height=h;
		els=null;
	},
	getSize:function(element) {		return {width:element.offsetWidth,height:element.offsetHeight};	},
	setRect:function(element,x,y,width,height,parentElement) {
		this.setPos(element,x,y,parentElement);
		this.setSize(element,width,height);
		element=null;
	},
	getRect:function(element,parentElement) {
		var pos=this.getPos(element,parentElement);
		var size=this.getSize(element);
		element=null;
    return {x:pos.x,y:pos.y,width:size.width,height:size.height};
	},
	getBorderWidth:function(element) {
		var l=parseInt(jsq.style.get(element,'borderLeftWidth'),10);
		var t=parseInt(jsq.style.get(element,'borderTopWidth'),10);
		var r=parseInt(jsq.style.get(element,'borderRightWidth'),10);
		var b=parseInt(jsq.style.get(element,'borderBottomWidth'),10);
		return {left:isNaN(l)?0:l,top:isNaN(t)?0:t,right:isNaN(r)?0:r,bottom:isNaN(b)?0:b};
	},
	getPadding:function(element) {
		var l=parseInt(jsq.style.get(element,'paddingLeft'),10);
		var t=parseInt(jsq.style.get(element,'paddingTop'),10);
		var r=parseInt(jsq.style.get(element,'paddingRight'),10);
		var b=parseInt(jsq.style.get(element,'paddingBottom'),10);
		return {left:isNaN(l)?0:l,top:isNaN(t)?0:t,right:isNaN(r)?0:r,bottom:isNaN(b)?0:b};
	},
	getMargin:function(element) {
		var l=parseInt(jsq.style.get(element,'marginLeft'),10);
		var t=parseInt(jsq.style.get(element,'marginTop'),10);
		var r=parseInt(jsq.style.get(element,'marginRight'),10);
		var b=parseInt(jsq.style.get(element,'marginBottom'),10);
		return {left:isNaN(l)?0:l,top:isNaN(t)?0:t,right:isNaN(r)?0:r,bottom:isNaN(b)?0:b};
	},
	getDocumentRect:function(doc) {
		if (!doc) doc=document;
		var docHeight=-1,winHeight=-1,bodyHeight=-1;
		var docWidth=-1,bodyWidth=-1,winWidth=-1;
		var margin=jsq.dom.getMargin(doc.body);

		var mode = doc.compatMode;
		if ( (mode || jsq.Browser.IE) && !jsq.Browser.Opera ) { // (IE, NS)
		  switch (mode) {
		     case 'CSS1Compat': 
		        docWidth = doc.docElement?doc.docElement.clientWidth:0;
		        docHeight = ((window.innerHeight && window.scrollMaxY) ?  window.innerHeight+window.scrollMaxY : -1);
		        winWidth = self.innerWidth || -1;
		        winHeight = Math.max((doc.docElement)?doc.docElement.clientHeight:0,self.innerHeight||-1);
		        bodyWidth = doc.body.offsetWidth + margin.left + margin.right;
		        bodyHeight = doc.body.offsetHeight + margin.top + margin.bottom;
		        break;
		     
		     default: 
		        winWidth = doc.body.scrollWidth;
		        winHeight= doc.body.scrollHeight;
		        //docHeight = doc.body.docHeight;
		        bodyWidth = doc.body.clientWidth;
		        bodyHeight = doc.body.clientHeight;
		        break;
		  }
		} else { // Safari & Opera
		  winWidth = self.innerWidth;
		  winHeight = self.innerHeight;
		  docWidth = doc.docElement.clientWidth;
		  docHeight = doc.docElement.docHeight;
		  bodyWidth = doc.body.offsetWidth + margin.left + margin.right;
		  bodyHeight = doc.docElement.clientHeight;
		}
		var w = [docWidth,bodyWidth,winWidth].sort(function(a, b){return(a-b);});
		var h = [docHeight,winHeight,bodyHeight].sort(function(a, b){return(a-b);});
		doc=null;
		return {width:w[2],height:h[2]};
	},
	show:function(element,x,y,parentElement) {
		jsq.style.set(element,'display','block');
		if (x && y) this.setPosition(element,x,y,parentElement);
	},
/*	showInline:function(element,x,y,parentElement) {
		swaf.style.set(element,'display','inline');
		if (x && y) this.setPosition(element,x,y,parentElement);
	},
	showStatic:function(element,x,y,parentElement) {
		swaf.style.set(element,'display','static');
	},*/
	hide:function(element) {
		jsq.style.set(element,'display','none');
	},
	toggle:function(element,x,y,parentElement) {
		var show=jsq.style.get(element,'display');
		if (show=='none') this.show(element,x,y,parentElement);
		else this.hide(element);
	},
/*	toggleInline:function(element,x,y,parentElement) {
		var show=swaf.style.get(element,'display');
		if (show=='none') this.showInline(element,x,y,parentElement);
		else this.hide(element);
	},*/
	swap:function(el1,el2) {
		if (el1.swapNode) {
			el1.swapNode(el2);
		} else {
			var p=el2.parentNode;
			var s=el2.nextSibling;
			el1.parentNode.insertBefore(el2,el1.nextSibling);
			p.insertBefore(el1,s);
		}
	},
	hideByTag:function(tagName,element) {
		var arrSelect=element.getElementsByTagName(tagName);
		for(var i=0;i<arrSelect.length;i++) {
			if (arrSelect[i].style.display=='none') continue;
			arrSelect[i].style.visibility='hidden';
		}
		arrSelect=null;
	},
	showByTag:function(tagName,element) {
		var arrSelect=element.getElementsByTagName(tagName);
		for(var i=0;i<arrSelect.length;i++) {
			arrSelect[i].style.visibility='visible';
		}
		arrSelect=null;
	},
	deleteElement:function(element) {
		try {
			element.innerHTML='';
	    var garbageBin = document.getElementById('IELeakGarbageBin');
	    if (!garbageBin) {
	        garbageBin = document.createElement('DIV');
	        garbageBin.id = 'IELeakGarbageBin';
	        garbageBin.style.display = 'none';
	        document.body.appendChild(garbageBin);
	    }
	    // move the element to the garbage bin
	    garbageBin.appendChild(element);
	    garbageBin.innerHTML = '';
	  } catch(e) {
	  }
	    element=null;
	},
	resetID:function(element) {
		var arr=element.childNodes;
		for(var i=0;i<arr.length;i++) {
			node=arr[i];
			if (node.nodeType==1 && node.id) {
				node.id='';
			}
		}
		arr=null;
	},
	cloneNode:function(element) {
		var retEl=element.cloneNode(true);
		jsq.dom.resetID(retEl);
		return retEl;
	}
};
